﻿using System;
using ProtoBuf;
using System.Linq;
using System.Text;
using Enyim.Caching;
using Ayatta.Contract;
using System.Web.Mvc;
using Web.Base.Security;
using System.Web.WebPages;
using Ayatta.Contract.Domain;
using System.Collections.Generic;
using Ayatta.Common.Extensions;
using Ayatta.Contract.Component;
using Web.Product.Upload.Models;

namespace Web.Product.Upload.Controllers
{
    public class HomeController : BaseController
    {
        public HomeController(ILogService logService, IBaseService baseService, IExtraService extraService, IStoreService storeService, IOrderService orderService, IGameService gameService, IAuctionService auctionService, IPassportService passportService, IPaymentService paymentService, IMemcachedClient memcachedClient)
            : base(logService, baseService, extraService, storeService, orderService, gameService, auctionService, passportService, paymentService, memcachedClient)
        {
        }

        public ActionResult Index()
        {
            var model = new HomeControllerModel.Index();
            model.Categories = GetCategoryRoot();
            model.ProductCategories = GetCategories(0);
            return View(model);
        }

        [HttpPost]
        public ActionResult Index(FormCollection form)
        {
            var time = DateTime.Now;
            const string prefix = "prop.";
            var errors = new List<object>();
            var identity = User.Identity.Identity();
            var result = new SkResult<object>();
            //var categoryId = form[prefix + "category"].AsInt();
            var productId = form[prefix + "id"].AsInt(0);
            var hierarchyId = form[prefix + "hierarchyid"].Split('/');
            int categoryId = 0, categoryRootId = 0;
            var categoryMiddleId = string.Empty;
            for (var i = 0; i < hierarchyId.Length; i++)
            {
                if (i == 0)
                {
                    categoryRootId = hierarchyId[i].AsInt();
                }
                else if (i == hierarchyId.Length - 1)
                {
                    categoryId = hierarchyId[i].AsInt();
                }
                else if (i != hierarchyId.Length - 2)
                {
                    categoryMiddleId += hierarchyId[i] + "/";
                }
                else
                {
                    categoryMiddleId += hierarchyId[i];
                }
            }
            if (categoryRootId < 0 || categoryId < 0)
            {
                var error = new { message = "类目错误！" };
                errors.Add(error);
            }
            var outerId = form[prefix + "outerId"] ?? string.Empty;

            var name = form[prefix + "name"];
            if (name.IsNullOrEmpty())
            {
                var error = new { name = prefix + "name", message = "请填写标题！" };
                errors.Add(error);
            }
            else if (name.Length > 60)
            {
                var error = new { name = prefix + "name", message = "不能超过60字符！" };
                errors.Add(error);
            }
            var subName = form[prefix + "subName"];
            if (!subName.IsNullOrEmpty() && subName.Length > 60)
            {
                var error = new { name = prefix + "subName", message = "不能超过60字符！" };
                errors.Add(error);
            }

            decimal itemPrice = 0;
            var priceField = form[prefix + "price"];
            if (priceField.IsNullOrEmpty())
            {
                var error = new { name = prefix + "price", message = "请填写价格！" };
                errors.Add(error);
            }
            else if (decimal.TryParse(priceField, out itemPrice))
            {
                var error = new { name = prefix + "price", message = "请输入数字（精确到2位小数）！" };
                errors.Add(error);
            }
            else if (itemPrice < 0 || itemPrice > 10000000)
            {
                var error = new { name = prefix + "price", message = "取值范围：0-10000000！" };
                errors.Add(error);
            }
            var itemQuantity = 0;
            var quantityField = form[prefix + "quantity"];
            if (quantityField.IsNullOrEmpty())
            {
                var error = new { name = prefix + "quantity", message = "请填写商品数量！" };
                errors.Add(error);
            }
            else if (int.TryParse(priceField, out itemQuantity))
            {
                var error = new { name = prefix + "quantity", message = "请输入数字（精确到2位小数）！" };
                errors.Add(error);
            }
            else if (itemQuantity < 0 || itemQuantity > 999999)
            {
                var error = new { name = prefix + "quantity", message = "取值范围：0-999999！" };
                errors.Add(error);
            }
            var desc = form[prefix + "desc"];
            if (desc.IsNullOrEmpty())
            {
                var error = new { name = prefix + "desc", message = "请填写商品描述！" };
                errors.Add(error);
            }
            else if (desc.Length < 5 || desc.Length > 20000)
            {
                var error = new { name = prefix + "desc", message = "商品描述为于5至25000个字符！" };
                errors.Add(error);
            }

            var subStock = form[prefix + "subStock"].As<byte>();

            var isTiming = false;
            var onlineTime = time;
            var itemStatus = ProductItemStatus.Online;
            var onlineTimeField = form[prefix + "onlineTime"];
            if (onlineTimeField == "0" || onlineTimeField == "1")
            {
                if (onlineTimeField == "1")
                {
                    itemStatus = ProductItemStatus.Offline;
                }
            }
            else if (!DateTime.TryParse(onlineTimeField, out onlineTime))
            {
                var error = new { name = prefix + "onlineTime", message = "请选择日期及时间！" };
                errors.Add(error);
            }
            else
            {
                isTiming = true;
            }

            var props = GetProps(categoryId);
            var saleProps = props.Where(o => o.IsSaleProp);
            var colorProps = props.Where(o => o.IsColorProp);
            var otherProps = props.Where(o => !o.IsSaleProp && !o.IsColorProp);

            var propValues = GetPropValues(categoryId);

            var skus = new List<Sku>();
            var saleKeys = (from prop in saleProps let temp = prop select propValues.Where(o => o.PropId == temp.Id).Select(o => prop.Id + ":" + o.Id).ToArray()).ToList();
            var skuKeys = GetSkuKeys(saleKeys);
            if (!skuKeys.IsNullOrEmpty())
            {
                foreach (var skuKey in skuKeys)
                {
                    if (skuKey.IsNullOrEmpty()) continue;
                    var priceParam = "sku.pric." + skuKey;
                    var quantityParam = "sku.quantity." + skuKey;

                    int quantity;
                    decimal price;

                    var priceVal = form[priceParam];
                    var quantityVal = form[quantityParam];
                    if (priceVal.IsNullOrEmpty() || !decimal.TryParse(priceVal, out price) ||
                        quantityVal.IsNullOrEmpty() || !int.TryParse(quantityVal, out quantity))
                    {
                        continue;
                    }
                    var sku = new Sku();
                    var nvs = skuKey.Split(';');
                    var propsName = string.Empty;
                    foreach (var nv in nvs)
                    {
                        var pid = nv.Split(':')[0].AsInt();
                        var vid = nv.Split(':')[1].AsInt();
                        var pn = props.First(o => o.Id == pid).Name;
                        var vn = propValues.First(o => o.Id == vid).Name;
                        propsName += string.Format("{0}:{1}:{2}:{3};", pid, vid, pn, vn);
                    }
                    sku.UserId = identity.Id;
                    sku.ItemId = 0;
                    sku.ProductId = productId;
                    sku.CategoryId = categoryId;
                    sku.CategoryRootId = categoryRootId;
                    sku.CategoryMiddleId = categoryMiddleId;
                    sku.OuterId = string.Empty;
                    sku.Properties = skuKey;
                    sku.PropertiesName = propsName.TrimEnd(';');
                    sku.Price = price;
                    sku.Quantity = quantity;
                    sku.SoldAmount = 0;
                    sku.Status = 0;
                    sku.CreatedOn = time;
                    sku.ModifiedOn = time;
                    skus.Add(sku);
                }
            }

            var itemImgs = new List<string>();
            var propImgs = new List<string>();
            foreach (var prop in colorProps)
            {
                var pid = prop.Id;
                var values = propValues.Where(o => o.PropId == pid);
                foreach (var value in values)
                {
                    var img = prefix + "img." + prop.Id + ":" + value.Id;
                    var file = form[img];
                    if (!file.IsNullOrEmpty())
                    {
                        propImgs.Add(file);
                    }
                }
            }
            var inputIdsBuilder = new StringBuilder();
            var inputStrsBuilder = new StringBuilder();
            var propsBuilder = new StringBuilder(props.Count);
            var propsNameBuilder = new StringBuilder(props.Count);

            foreach (var prop in otherProps)
            {
                var pvid = form[prefix + prop.Id];
                if (pvid.IsNullOrEmpty())
                {
                    continue;
                }
                if (prop.Type == PropType.Text)
                {
                    inputIdsBuilder.AppendFormat("{0},", prop.Id);
                    inputStrsBuilder.AppendFormat("{0},", pvid);
                }
                else if (prop.Type == PropType.MultiCheck || prop.Type == PropType.MultiCheckText)
                {
                    var kvs = pvid.Split(',');
                    if (kvs.Length > 0)
                    {
                        foreach (var kv in kvs)
                        {
                            var vid = kv.Split(':')[1].AsInt();
                            var val = propValues.FirstOrDefault(o => o.Id == vid);
                            if (val == null) continue;
                            propsBuilder.AppendFormat("{0}:{1};", prop.Id, val.Id);
                            propsNameBuilder.AppendFormat("{0}:{1}:{2}:{3};", prop.Id, val.Id, prop.Name, val.Name);
                        }
                    }
                }
                else
                {
                    var vid = pvid.Split(':')[1].AsInt();
                    var val = propValues.FirstOrDefault(o => o.Id == vid);
                    if (val != null)
                    {
                        propsBuilder.AppendFormat("{0}:{1};", prop.Id, val.Id);
                        propsNameBuilder.AppendFormat("{0}:{1}:{2}:{3};", prop.Id, val.Id, prop.Name, val.Name);
                    }
                }
            }

            var item = new ProductItem();
            item.UserId = identity.Id;
            item.ProductId = productId;
            item.CategoryId = categoryId;
            item.CategoryRootId = categoryRootId;
            item.CategoryMiddleId = categoryMiddleId;
            item.OuterId = outerId;
            item.Name = name;
            item.SubName = subName;
            item.Price = itemPrice;
            item.Quantity = itemQuantity;
            item.RewardRate = 0.5m;
            item.Properties = propsBuilder.ToString().TrimEnd(';');
            item.PropertiesName = propsNameBuilder.ToString().TrimEnd(';');
            item.PropertiesAlias = string.Empty;
            item.InputIds = inputIdsBuilder.ToString().TrimEnd(',');
            item.InputStrs = inputStrsBuilder.ToString().TrimEnd(',');
            item.Picture = string.Empty;
            item.ItemImgs = string.Empty;
            item.PropImgs = string.Empty;
            item.Weight = 0M;
            item.Size = string.Empty;
            item.Description = desc;
            item.IsVirtual = false;

            item.SubStock = subStock;
            item.AutoFill = 0;
            item.IsTiming = isTiming;
            item.ShowCase = false;
            item.OnlineTime = onlineTime;
            item.OfflineTime = time.AddYears(2);
            item.Sale = 0;
            item.Status = itemStatus;
            item.CreatedBy = User.Identity.Name;
            item.Skus = skus;

            if (skus.Count > 0)
            {
                if (itemPrice < skus.Min(o => o.Price) || itemPrice > skus.Max(o => o.Price))
                {
                    var error = new { name = prefix + "quantity", message = "商品数量不对！" };
                    errors.Add(error);
                }
                item.Quantity = skus.Sum(o => o.Quantity);
            }
            var d = StoreService.CreateProductItem(item);
            return Json(d);
        }


        private IList<Category> GetCategoryRoot()
        {
            var file = Server.MapPath("~/App_Data/category.root.bin");
            using (var stream = System.IO.File.OpenRead(file))
            {
                return Serializer.Deserialize<IList<Category>>(stream);
            }
        }
    }
}
